iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 8
1
Mobile Development

Android 開發經驗三十天系列 第 8

[Android 開發經驗三十天]D8一自定義View筆記(下)

  • 分享至 

  • xImage
  •  

人生難得幾回瘋,不寫更何待,來來來寫完這篇再說吧/images/emoticon/emoticon02.gif

繼續介紹吧!!!

onLayout

1.作用:計算View的位置,在測量過後要知道位置在哪應該也很正常!
ViewGroup的話就是一層一層計算下來都知道在哪之後在合併
l t r b分別是上下左右

layout(int l, int t, int r, int b)
  • 注意 : 其實也可以直接寫 layout(0, 0, 50,50) 只是這樣非常不尊重算出來的結果
    onLayout傳入 左上右下四個點的座標
childView.getMeasuredWidth(), childView.getMeasuredHeight());

這是你測量出來的寬高

onLayout完成後才能拿到 getWidth() getHeight()
這個是右邊減去左邊算出來的, measure是測量的

onDraw

1.作用:用Canavas將View畫上去
原始碼順序大概是這樣,就不貼了
畫背景 畫內容 畫子類 畫滑動條 (每種view其實都有滑動條)

onDraw()
真正繪製的地方 底層其實是canvas
1.畫背景
2.畫content
3.畫children
4.畫滾動條 (不管是啥都有滾動條)
接下來綜合三種貼個原始碼,可以看到View是自定義的 然後有個黑色框框在正中間

自定義一個View一開始會顯示Hello World,在按一下會變goodNight World

<com.example.ktforfilemanager.HelloView
    android:layout_width="200dp"
    android:layout_height="200dp"
    android:layout_centerInParent="true" >

</com.example.ktforfilemanager.HelloView>

HelloView

 private val mPaint: Paint

    private val mRect: Rect

    private var mCount: Int = 0
    private var  uuko:String="hello world"


    init {
        mPaint = Paint(Paint.ANTI_ALIAS_FLAG)
        mRect = Rect()
        setOnClickListener(this)
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        mPaint.setColor(Color.GREEN)
        canvas.drawRect(0F, 0F, width.toFloat(), height.toFloat(), mPaint)
        mPaint.setColor(Color.YELLOW)
        mPaint.setTextSize(40F)
        val text = uuko
        mPaint.getTextBounds(text, 0, text.length, mRect)
        val textWidth = mRect.width()
        val textHeight = mRect.height()
        canvas.drawText(
            text,
            (getWidth() / 2 - textWidth / 2).toFloat(),
            (getHeight() / 2 + textHeight / 2).toFloat(),
            mPaint
        )
    }

    override fun onClick(v: View) {
        mCount++
        if (mCount%2==1){
            uuko="hello world"
        }else{
            uuko="goodNight world"
        }


        invalidate()
    }

問題與討論 : onDraw為何會使用有問題 ?

如果想畫一個框框顯示在中間,可以用下面的 但是在onDraw會有點問題,可能需要修改

<com.example.ktforfilemanager.MyTestView
    android:background="@color/colorPrimary"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button

        android:layout_width="200dp"
        android:layout_height="200dp"
        android:background="#333444"
        android:id="@+id/ChildView" />
</com.example.ktforfilemanager.MyView>


override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec)

    val childView = getChildAt(0)
    measureChild(childView, widthMeasureSpec, heightMeasureSpec)
}

override fun onLayout(p0: Boolean, l: Int, t: Int, r: Int, b: Int) {
    var child=childCount-1
    for (i in 0.. child){
        var chView=getChildAt(i)
        var  width:Int = chView.measuredWidth
        var  height :Int = chView.measuredHeight

        var  left = (r - width) / 2;
        var  top = (b - height) / 2;
        var  right =  left + width
        var  bottom = top + height

        var myViewDataClass=MyViewDataClass(l.toFloat(),t.toFloat(),r.toFloat(),b.toFloat())
        fallObjects?.add(myViewDataClass)
        chView.layout(left, top, right,bottom);
        invalidate()
    }
}
   


上一篇
[Android經驗三十天]Day7一自定義View觀念 (中)
下一篇
[Android 開發經驗三十天]D9一自定義View筆記一實作跳跳球View
系列文
Android 開發經驗三十天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言